home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
presto
/
presto10.lha
/
src
/
atomic_int.h
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-11
|
8KB
|
311 lines
#ifndef __presto__atomic_int_h__
#define __presto__atomic_int_h__
//
// Atomic ints are good for counters, etc... All integer operations
// on them are defined.
//
// Modification History:
//
// 09-Aug-1991 PBD
// Removed non-ANSI macros and expanded in-place.
//
// 14-Jan-1989 JEF
// Added 'value' member function to both classes.
//
// 04-Jan-1989 JEF
// Include lock/unlock pair around operator INT in both classes.
//
// 28-Dec-1989 JEF
// Add class HC_AtomicInt. This new version of an atomic integer utilizes
// the HC_Spinlock, providing faster atomic integer operations when there is
// high contention for the atomic integer.
//
//
// Original atomic integer class.
//
class AtomicInt {
Spinlock ai_lock;
int ai_val;
public:
AtomicInt()
{ ai_val = 0; }
AtomicInt(int x)
{ ai_val = x; }
AtomicInt(AtomicInt& x) // should we lock x?
{ ai_val = x.ai_val;}
~AtomicInt()
{ unlock(); }
operator int()
{ lock(); register int tmp = ai_val; unlock();
return tmp; }
void lock() // Careful....
{ ai_lock.lock(); }
void unlock()
{ ai_lock.unlock(); }
int& val() // use at your own risk
{ return ai_val; }
int value() // retrieve current value safely
{ lock(); register int tmp = ai_val; unlock();
return tmp; }
inline int operator= (int x)
{
lock(); register int tmp = ai_val = x; unlock();
return tmp;
}
inline int operator+= (int x)
{
lock(); register int tmp = ai_val += x; unlock();
return tmp;
}
inline int operator*= (int x)
{
lock(); register int tmp = ai_val *= x; unlock();
return tmp;
}
inline int operator/= (int x)
{
lock(); register int tmp = ai_val /= x; unlock();
return tmp;
}
inline int operator%= (int x)
{
lock(); register int tmp = ai_val %= x; unlock();
return tmp;
}
inline int operator^= (int x)
{
lock(); register int tmp = ai_val ^= x; unlock();
return tmp;
}
inline int operator&= (int x)
{
lock(); register int tmp = ai_val &= x; unlock();
return tmp;
}
inline int operator|= (int x)
{
lock(); register int tmp = ai_val |= x; unlock();
return tmp;
}
inline int operator<<= (int x)
{
lock(); register int tmp = ai_val <<= x; unlock();
return tmp;
}
inline int operator>>= (int x)
{
lock(); register int tmp = ai_val >>= x; unlock();
return tmp;
}
inline int operator++ () // prefix
{
lock(); register int tmp = ++ai_val; unlock();
return tmp;
}
#ifdef __DECCXX /* or rather, an ARM compliant compiler */
inline int operator++ (int x) // postfix
{
lock(); register int tmp = ai_val++; unlock();
return tmp;
}
#endif /* _DECCXX */
inline int operator-- () // prefix
{
lock(); register int tmp = --ai_val; unlock();
return tmp;
}
#ifdef __DECCXX /* as above */
inline int operator-- (int x) // postfix
{
lock(); register int tmp = ai_val--; unlock();
return tmp;
}
#endif /* __DECCXX */
};
#ifdef sequent
#ifdef i386
//
// Atomic integer class specialized for use in high-contention situations.
//
// The best 'C++' way to do this is probably to make the AtomicInt functions
// lock and unlock be virtual, and to then derive class HC_AtomicInt from
// class AtomicInt, providing new lock and unlock functions specific to the
// HC_Spinlock (as given below). However, the performance of the member
// functions of the new derived class is poor compared to the performance
// realized when a new base class is created (by copying and modifying the
// original base class). In the interest of speed, we'll go with the new
// base class instead of the derived class.
//
//
// The clean (but SLOW) way... (note - must make ai_val in base class
// be protected).
//
//class HC_AtomicInt : public AtomicInt {
// HC_Spinlock hc_ai_lock;
//public:
// HC_AtomicInt (); // base class constructor
// HC_AtomicInt (int x) : (x) {} // is called to do
// HC_AtomicInt (AtomicInt& x) : (x) {} // all the work
//
// ~HC_AtomicInt ()
// { unlock(); }
//
// //
// // Make base class lock and unlock functions be virtual. Then
// // override them with new versions specific to the high-contention
// // spinlock.
// //
// void lock () // Careful....
// {
// hc_ai_lock.lock ();
// cout << "ai - derived class lock (HC_Spinlock.lock)\n";
// cout.flush ();
// }
//
// void unlock ()
// {
// cout << "ai - derived class unlock (HC_Spinlock.unlock)\n";
// cout.flush ();
// hc_ai_lock.unlock();
// }
//};
//
// The fast way...
//
class HC_AtomicInt {
HC_Spinlock ai_lock;
int ai_val;
public:
HC_AtomicInt()
{ ai_val = 0; }
HC_AtomicInt(int x)
{ ai_val = x; }
HC_AtomicInt(HC_AtomicInt& x) // should we lock x?
{ ai_val = x.ai_val;}
~HC_AtomicInt()
{ unlock(); }
operator int()
{ lock(); register int tmp = ai_val; unlock();
return tmp; }
void lock() // Careful....
{ ai_lock.lock(); }
void unlock()
{ ai_lock.unlock(); }
int& val() // use at your own risk
{ return ai_val; }
int value() // retrieve current value safely
{ lock(); register int tmp = ai_val; unlock();
return tmp; }
inline int operator= (int x)
{
lock(); register int tmp = ai_val = x; unlock();
return tmp;
}
inline int operator+= (int x)
{
lock(); register int tmp = ai_val += x; unlock();
return tmp;
}
inline int operator*= (int x)
{
lock(); register int tmp = ai_val *= x; unlock();
return tmp;
}
inline int operator/= (int x)
{
lock(); register int tmp = ai_val /= x; unlock();
return tmp;
}
inline int operator%= (int x)
{
lock(); register int tmp = ai_val %= x; unlock();
return tmp;
}
inline int operator^= (int x)
{
lock(); register int tmp = ai_val ^= x; unlock();
return tmp;
}
inline int operator&= (int x)
{
lock(); register int tmp = ai_val &= x; unlock();
return tmp;
}
inline int operator|= (int x)
{
lock(); register int tmp = ai_val |= x; unlock();
return tmp;
}
inline int operator<<= (int x)
{
lock(); register int tmp = ai_val <<= x; unlock();
return tmp;
}
inline int operator>>= (int x)
{
lock(); register int tmp = ai_val >>= x; unlock();
return tmp;
}
inline int operator++ ()
{
lock(); register int tmp = ai_val++; unlock();
return tmp;
}
inline int operator-- ()
{
lock(); register int tmp = ai_val--; unlock();
return tmp;
}
int preinc()
{ lock(); register int tmp = ++ai_val; unlock();
return tmp; }
int postinc()
{ lock(); register int tmp = ai_val++; unlock();
return tmp; }
int predec()
{ lock(); register int tmp = --ai_val; unlock();
return tmp; }
int postdec()
{ lock(); register int tmp = ai_val--; unlock();
return tmp; }
// Should probably have the rest of the operators here too...
};
#endif /* i386 */
#endif /* sequent */
#endif /* __presto__atomic_int_h__ */